package chat.ws;


import chat.config.GetHttpSessionConfigurator;
import chat.service.IChatService;
import com.alibaba.fastjson.JSONObject;
import common.model.chat.ChatRoom;
import common.model.chat.Message;
import io.jsonwebtoken.io.IOException;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint(
        value = "/chat/{userType}",
        configurator = GetHttpSessionConfigurator.class
)
@Component
public class ChatEndpoint implements ApplicationContextAware {

    private static ApplicationContext applicationContext;
    private IChatService chatService;

    // 分别存储在线用户和在线管理员
    private static final Map<String, Session> onlineUsers = new ConcurrentHashMap<>();
    private static final Map<String, Session> onlineAdmins = new ConcurrentHashMap<>();

     // 存储用户-管理员的会话关系
    private static final Map<String, String> userAdminSessions = new ConcurrentHashMap<>();

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ChatEndpoint.applicationContext = applicationContext;
    }
    // 在每个连接开始时获取 chatService
    private void initChatService() {
        if (chatService == null) {
            chatService = applicationContext.getBean(IChatService.class);
        }
    }

    //连接时调用
    @OnOpen
    public void onOpen(Session session, EndpointConfig config, @PathParam("userType") String userType) throws java.io.IOException {
        try {
            initChatService(); // 确保 chatService 在使用前被初始化
            System.out.println("开始处理新连接，userType: " + userType);

            // 获取用户信息
            String userIdStr = (String) config.getUserProperties().get("userId");
            System.out.println("从配置获取的userIdStr: " + userIdStr);

            // 转换为 Long 类型
            Long userId = null;
            if (userIdStr != null && !userIdStr.trim().isEmpty()) {
                try {
                    userId = Long.parseLong(userIdStr);
                    System.out.println("成功转换userId为Long: " + userId);
                } catch (NumberFormatException e) {
                    System.out.println("用户ID格式错误: " + userIdStr);
                    // 处理错误，比如关闭连接
                    try {
                        session.close(new CloseReason(CloseReason.CloseCodes.VIOLATED_POLICY, "用户ID格式错误"));
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                    return;
                }
            }

            String nickName = (String) config.getUserProperties().get("nickName");
            System.out.println("获取的nickName: " + nickName);

            session.getUserProperties().put("userId", userId);
            session.getUserProperties().put("nickName", nickName);
            session.getUserProperties().put("userType", userType);
            System.out.println("已将用户信息存入session属性");

            if (userId == null || userType == null) {
                System.out.println("缺少必要的用户信息: userId=" + userId + ", userType=" + userType);
                try {
                    session.close(new CloseReason(CloseReason.CloseCodes.VIOLATED_POLICY, "缺少必要的用户信息"));
                } catch (IOException | java.io.IOException e) {
                    e.printStackTrace();
                }
                return;
            }

            System.out.println("用户类型: " + userType);

            // 根据用户类型存储会话
            if ("user".equals(userType)) {
                System.out.println("处理用户连接，userId: " + userId);
                onlineUsers.put(userId + "", session);
                // 通知所有在线管理员有新用户连接
                notifyAdminsNewUser(userId + "", nickName);
                //是否已有已创建的活跃聊天室
                if(!chatService.isChatRoomCreated(userId)){
                    System.out.println("为用户 " + userId + " 创建新聊天室");
                    //没有，则创建一个新的聊天室用于存储会话信息
                    ChatRoom chatRoom = new ChatRoom();
                    chatRoom.setNickName(nickName);
                    chatRoom.setUserId(userId);
                    chatRoom.setConversationId(userId + System.currentTimeMillis() + "");
                    chatRoom.setStatus(1);
                    chatRoom.setAdminId(0L);
                    chatService.insertChatRoom(chatRoom);
                    System.out.println("已创建聊天室: " + chatRoom.getConversationId());
                } else {
                    System.out.println("用户 " + userId + " 已有活跃聊天室");
                }

            } else if ("admin".equals(userType)) {
                System.out.println("处理管理员连接，adminId: " + userId);
                onlineAdmins.put(userId + "", session);
                //查询活跃的聊天室
                List<ChatRoom> activeChatRooms = chatService.getActiveChatRooms();
                System.out.println("找到 " + activeChatRooms.size() + " 个未分配活跃聊天室");

                for (ChatRoom chatRoom : activeChatRooms) {
                    //分配聊天室
                    chatRoom.setAdminId(userId);
                    System.out.println("分配管理员ID " + chatRoom.getAdminId() + " 给聊天室 " + chatRoom.getConversationId());
                    chatService.updateChatRoom(chatRoom);
                }
                // 向管理员发送已对接的所有会话
                sendOnlineUsersToAdmin(session);
                System.out.println("已向管理员发送在线用户列表");
            } else {
                System.out.println("未知用户类型: " + userType);
                try {
                    session.close(new CloseReason(CloseReason.CloseCodes.VIOLATED_POLICY, "未知用户类型"));
                } catch (IOException | java.io.IOException e) {
                    e.printStackTrace();
                }
                return;
            }
            System.out.println("连接处理完成！！！！！！");

        } catch (Exception e) {
            System.out.println("在处理连接时发生异常: " + e.getMessage());
            e.printStackTrace();
            try {
                session.close(new CloseReason(CloseReason.CloseCodes.UNEXPECTED_CONDITION, "服务器内部错误"));
            } catch (IOException | java.io.IOException ex) {
                ex.printStackTrace();
            }
        }
    }
    @OnMessage
    public void onMessage(String message, Session session) {
        try {
            System.out.println("收到原始消息: "+message);

            // 解析消息JSON
            JSONObject jsonMessage = JSONObject.parseObject(message);
            Long fromId = (Long) session.getUserProperties().get("userId");
            String userType = (String) session.getUserProperties().get("userType");
            String toId = jsonMessage.getString("toId");
            String content = jsonMessage.getString("content");

            System.out.println("消息解析 - 发送方: " +
                    fromId +", 用户类型: "+userType+", 接收方: "+toId+", 内容: " +content);

            // 验证必要字段
            if (content == null || content.trim().isEmpty()) {
                System.out.println("消息内容为空，发送方: "+userType+fromId);
                return;
            }



            // 构建发送的消息
            Long timestamp = System.currentTimeMillis();

            JSONObject sendMsg = new JSONObject();
            sendMsg.put("fromId", fromId);
            sendMsg.put("content", content);
            sendMsg.put("timestamp", timestamp);
            sendMsg.put("type", "message");

            String sendMsgStr = sendMsg.toJSONString();
            System.out.println("构建发送消息: "+sendMsgStr);

            // 根据用户类型转发消息
            if ("user".equals(userType)) {
                System.out.println("用户" + fromId + "发送消息");
                // 获取聊天室信息
                ChatRoom chatRoom = chatService.getChatRoom(fromId);
                System.out.println(chatRoom);
                chatRoom.setLastMessage(content);
                chatRoom.setLastMessageTime(timestamp);
                chatService.updateChatRoom(chatRoom);
                //记录发送的消息
                Message newMessage = new Message();
                newMessage.setContent(content);
                newMessage.setTimestamp(timestamp);
                newMessage.setConversationId(chatRoom.getConversationId());
                System.out.println(session.getId());
                newMessage.setFromId(fromId);
                newMessage.setToId(Long.valueOf(toId));
                newMessage.setFromType(userType);
                newMessage.setToType("admin");
                newMessage.setMessageType("message");
                newMessage.setStatus(1);
                chatService.insertMessage(newMessage);
                // 用户发给管理员
                String adminId = userAdminSessions.get(fromId);
                if (adminId != null && onlineAdmins.containsKey(adminId)) {
                    System.out.println("转发给已分配管理员: "+adminId);
                    onlineAdmins.get(adminId).getBasicRemote().sendText(sendMsgStr);
                } else {
                    // 分配一个在线管理员
                    System.out.println("为用户" + fromId + "分配管理员");
                    assignAdminToUser(fromId + "", sendMsg);
                }

            } else if ("admin".equals(userType)) {
                System.out.println("管理员" + fromId + "发送消息");
                // 获取聊天室信息
                ChatRoom chatRoom = chatService.getChatRoom(Long.valueOf(toId));
                System.out.println(chatRoom);
                chatRoom.setLastMessage(content);
                chatRoom.setLastMessageTime(timestamp);
                chatService.updateChatRoom(chatRoom);
                //记录发送的消息
                Message newMessage = new Message();
                newMessage.setContent(content);
                newMessage.setTimestamp(timestamp);
                newMessage.setConversationId(chatRoom.getConversationId());
                System.out.println(session.getId());
                newMessage.setFromId(fromId);
                newMessage.setToId(Long.valueOf(toId));
                newMessage.setFromType(userType);
                newMessage.setToType("user");
                newMessage.setMessageType("message");
                newMessage.setStatus(1);
                chatService.insertMessage(newMessage);

                // 管理员发给用户
                if (toId != null && onlineUsers.containsKey(toId)) {
                    System.out.println("管理员" + fromId + "发送给用户 " + toId);
                    onlineUsers.get(toId).getBasicRemote().sendText(sendMsgStr);
                    userAdminSessions.put(toId, fromId + ""); // 更新会话关系
                    System.out.println("更新用户" + toId + "与管理员 " + fromId + " 的会话关系");
                } else {
                    System.out.println("管理员" + fromId + "尝试发送给不存在的用户: "+toId);
                }

            } else {
                System.out.println("未知用户类型: "+userType);
            }

            System.out.println("消息处理完成 - 发送方: "+ userType + fromId);

        } catch (Exception e) {
            System.out.println("处理消息时发生异常"+e);
            e.printStackTrace();
        }
    }

    //连接关闭时被调用
    @OnClose
    public void onClose(Session session) throws java.io.IOException {
        Long userIdLong = (Long) session.getUserProperties().get("userId");
        String userId = (userIdLong != null) ? userIdLong.toString() : null;
        String userType = (String) session.getUserProperties().get("userType");

        if (userId == null || userType == null) {
            System.out.println("关闭连接时缺少必要的用户信息");
            return;
        }

        if ("user".equals(userType)) {
            onlineUsers.remove(userId);
            // 通知关联的管理员用户已断开
            String adminId = userAdminSessions.get(userId);
            if (adminId != null) {
                notifyAdminUserDisconnected(adminId, userId);
                userAdminSessions.remove(userId);
            }
        } else if ("admin".equals(userType)) {
            onlineAdmins.remove(userId);
            // 处理该管理员的所有会话
            handleAdminDisconnection(userId);
        }
    }
    // 其他辅助方法...
    private void notifyAdminsNewUser(String userId, String nickName) {
        try {
            JSONObject msg = new JSONObject();
            msg.put("type", "newUser");
            msg.put("userId", userId);
            msg.put("nickName", nickName);
            for (Session adminSession : onlineAdmins.values()) {
                adminSession.getBasicRemote().sendText(msg.toJSONString());
            }
        } catch (IOException | java.io.IOException e) {
            e.printStackTrace();
        }
    }
    private void sendOnlineUsersToAdmin(Session adminSession) throws java.io.IOException {
        JSONObject msg = new JSONObject();
        msg.put("type", "onlineUsers");
        msg.put("users", onlineUsers.keySet());
        adminSession.getBasicRemote().sendText(msg.toJSONString());
    }
    //分配管理员
    private void assignAdminToUser(String userId, JSONObject message) {
        // 简单的轮询分配
        for (String adminId : onlineAdmins.keySet()) {
            try {
                onlineAdmins.get(adminId).getBasicRemote().sendText(message.toJSONString());
                userAdminSessions.put(userId, adminId);
                break;
            } catch (IOException e) {
                e.printStackTrace();
            } catch (java.io.IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
    private void notifyAdminUserDisconnected(String adminId, String userId) {
        JSONObject msg = new JSONObject();
        msg.put("type", "userDisconnected");
        msg.put("userId", userId);
        try {
            onlineAdmins.get(adminId).getBasicRemote().sendText(msg.toJSONString());
        } catch (IOException | java.io.IOException e) {
            e.printStackTrace();
        }
    }
    private void handleAdminDisconnection(String adminId) throws java.io.IOException {
        // 通知所有用户该管理员已断开
        JSONObject msg = new JSONObject();
        msg.put("type", "adminDisconnected");
        msg.put("adminId", adminId);
        for (Session userSession : onlineUsers.values()) {
            userSession.getBasicRemote().sendText(msg.toJSONString());
        }
    }
}
